import numpy as np
import matplotlib.pyplot as plt
# ）以下通过数据用逻辑回归算法问题来分析问题：
# 现有一数据集logist.Txt，要求给定的数据来完成如下要求：
# ①	要求导入相关包并加载logistics.txt数据。（5）
data=np.loadtxt('logist.txt',delimiter=',')
# ②	要求将数据正确切分。（5）
x=data[:,:-1]
y=data[:,-1]
# ③	要求特征缩放（标准化特征缩放，其它特征缩放得分一半）（5）
# miu=np.mean(x,axis=0)
# sigma=np.std(x,axis=0)
# x=(x-miu)/sigma
max_x=np.max(x,axis=0)
min_x=np.min(x,axis=0)
x=(x-min_x)/(max_x-min_x)
# ④	进行数据拼接，并且将数据按4：1比例分成训练集和测试集（5）
X=np.c_[np.ones(len(x)),x]
num=int(0.8*len(x))
train_x,test_x=np.split(X,[num,])
train_y,test_y=np.split(y,[num,])

# ⑤	正确写出预测模型函数（5）
def model(x,theta):
    return x.dot(theta)
def sigmoid(z):
    return 1/(1+np.exp(-z))
# ⑥	正确写出代价（损失）函数（5）
def cost(h,y):
    m=len(y)
    return -1/m*np.sum(y*np.log(h)+(1-y)*np.log(1-h))
# ⑦	正确梯度函数，要求学习率0.1，迭代步长10000（5）
def grad(x,y,alpha=0.1,iter0=10000):
    m,n=x.shape
    theta=np.zeros(n)
    J=np.zeros(iter0)
    for i in range(iter0):
        z=model(x,theta)
        h=sigmoid(z)
        J[i]=cost(h,y)
        dt=1/m*x.T.dot(h-y)
        theta-=alpha*dt
    return h,theta,J
# ⑧	正确写出正确率（accurancy）函数（5）
def score(h,y):
    return np.mean(y==[h>0.5])
# ⑨	要求输出权重值，和准确率值（5）
train_h,theta,J=grad(train_x,train_y)
print(theta)
print(score(train_h,train_y))
# ⑩	数据可视化：
# （1）画出代价函数图（2）
plt.plot(J)
plt.show()
# （2）画出样本点，并画出边界线。（3）
plt.scatter(x[:,0],x[:,1],c=y)

min_x1=np.min(x[:,0])
max_x1=np.max(x[:,0])
min_x2=-(theta[0]+theta[1]*min_x1)/theta[2]
max_x2=-(theta[0]+theta[1]*max_x1)/theta[2]
plt.plot([min_x1,max_x1],[min_x2,max_x2])
plt.show()

